package adventure.commands;

import adventure.*;
import colour.ColourUtil;
import player.*;

/**
 *
 * @author Michael Hanns
 *
 */
public class Map extends AbstractCommand {

    public Map(Adventure a) {
        super(a, new String[]{"MAP"});
    }

    @Override
    public String validateAndExecute(Player p, String[] args) {
        if (args.length == 1) {
            return drawMap(p);
        } else {
            return "Command not recognised.";
        }
    }

    private String drawMap(Player p) {
        // Init the lines array
        String mapLines[] = new String[20];
        for (int y = 0; y < mapLines.length; y++) {
            mapLines[y] = "";
        }

        int fromX = p.x() - 5;
        int fromY = p.y() - 4;

        String[] room;
        // Fill in map lines with the map
        for (int x = 0; x < 11; x++) {
            for (int y = 0; y < 9; y++) {
                // Get the room
                room = drawRoom(p, fromX + x, fromY + y, p.z(), mapLines);

                // Concatonate the room to the map
                mapLines[20 - (y * 2) - 2] += room[0];
                mapLines[20 - (y * 2) - 1] += room[1];
            }
        }

        // Concatonate the lines
        String mapOut = mapLines[0];
        for (int x = 1; x < mapLines.length; x++) {
            mapOut += "\n" + mapLines[x];
        }


        return mapOut;
    }

    private String[] drawRoom(Player p, int x, int y, int z, String map[]) {
        String[] room = new String[3];
        // If room doesn't exist, draw a blank
        if (!rooms.roomExists(x, y, z)) {
            if (rooms.roomExists(x, y + 1, z) && rooms.roomExists(x - 1, y, z)) {
                room[0] = " ---";
                room[1] = "|###";
            } else if (rooms.roomExists(x, y + 1, z) && !rooms.roomExists(x - 1, y, z)) {
                room[0] = " ---";
                room[1] = "####";
            } else if (!rooms.roomExists(x, y + 1, z) && rooms.roomExists(x - 1, y, z) && rooms.roomExists(x - 1, y + 1, z)) {
                room[0] = "|###";
                room[1] = "|###";
            } else if (!rooms.roomExists(x, y + 1, z) && rooms.roomExists(x - 1, y, z)) {
                room[0] = " ###";
                room[1] = "|###";
            } else if (rooms.roomExists(x - 1, y + 1, z)) {
                room[0] = " ###";
                room[1] = "####";
            } else {
                room[0] = "####";
                room[1] = "####";
            }

            return room;
        }
        
        // Get the north exit
        if (rooms.isBlocked(x, y, z, 'N')) {
            if (rooms.roomExists(x, y + 1, z) && rooms.isBlocked(x, y + 1, z, 'S')) {
                room[0] = " ---";
            } else if (rooms.roomExists(x, y + 1, z) && rooms.isLocked(x, y + 1, z, 'S')) {
                room[0] = " -" + ColourUtil.colourise("▼", ColourUtil.red) + "-";
            } else if (rooms.roomExists(x, y + 1, z) && rooms.isClosed(x, y + 1, z, 'S')) {
                room[0] = " -" + ColourUtil.colourise("▼", ColourUtil.yellow) + "-";
            } else if (rooms.roomExists(x, y + 1, z)) {
                room[0] = " -▼-";
            } else {
                room[0] = " ---";
            }
        } else if (rooms.isLocked(x, y, z, 'N')) {
            if (rooms.isBlocked(x, y + 1, z, 'S')) {
                room[0] = " -" + ColourUtil.colourise("▲", ColourUtil.red) + "-";
            } else if (rooms.isLocked(x, y + 1, z, 'S')) {
                room[0] = " " + ColourUtil.colourise("-=-", ColourUtil.red);
            } else if (rooms.isClosed(x, y + 1, z, 'S')) {
                room[0] = " " + ColourUtil.colourise("-", ColourUtil.red) + ColourUtil.colourise("▼", ColourUtil.yellow) + ColourUtil.colourise("-", ColourUtil.red);
            } else {
                room[0] = " " + ColourUtil.colourise("-", ColourUtil.red) + "▼" + ColourUtil.colourise("-", ColourUtil.red);
            }
        } // If the north is closed
        else if (rooms.isClosed(x, y, z, 'N')) {
            // North is closed - print a one-way doorway for the least obstructured path
            if (rooms.isBlocked(x, y + 1, z, 'S')) {
                room[0] = " -" + ColourUtil.colourise("▲", ColourUtil.yellow) + "-";
            } else if (rooms.isLocked(x, y + 1, z, 'S')) {
                room[0] = " " + ColourUtil.colourise("-", ColourUtil.red) + ColourUtil.colourise("▲", ColourUtil.yellow) + ColourUtil.colourise("-", ColourUtil.red);
            } else if (rooms.isClosed(x, y + 1, z, 'S')) {
                room[0] = " " + ColourUtil.colourise("-=-", ColourUtil.yellow);
            } else {
                room[0] = " " + ColourUtil.colourise("-", ColourUtil.yellow) + "▼" + ColourUtil.colourise("-", ColourUtil.yellow);
            }
        } // If the north is NOT obstructured
        else {
            // Print a one-way doorway for blocked/closed/locked or an open otherwise
            if (rooms.isBlocked(x, y + 1, z, 'S')) {
                room[0] = " -▲-";
            } else if (rooms.isLocked(x, y + 1, z, 'S')) {
                room[0] = " " + ColourUtil.colourise("-", ColourUtil.red) + "▲" + ColourUtil.colourise("-", ColourUtil.red);
            } else if (rooms.isClosed(x, y + 1, z, 'S')) {
                room[0] = " " + "-" + ColourUtil.colourise("-", ColourUtil.yellow) + "▲" + ColourUtil.colourise("-", ColourUtil.yellow);
            } else {
                room[0] = "    ";
            }
        }
        
        
        
        // Get the west exit
        if (rooms.isBlocked(x, y, z, 'W')) {
            if (rooms.roomExists(x-1, y, z) && rooms.isBlocked(x-1, y, z, 'E')) {
                room[1] = "|";
            } else if (rooms.roomExists(x-1, y, z) && rooms.isLocked(x-1, y, z, 'E')) {
                room[1] = ColourUtil.colourise("►", ColourUtil.red);
            } else if (rooms.roomExists(x-1, y, z) && rooms.isClosed(x-1, y, z, 'E')) {
                room[1] = ColourUtil.colourise("►", ColourUtil.yellow);
            } else if (rooms.roomExists(x-1, y, z)) {
                room[1] = "►";
            } else {
                room[1] = "|";
            }
        } else if (rooms.isLocked(x, y, z, 'W')) {
            if (rooms.roomExists(x-1, y, z) && rooms.isBlocked(x-1, y, z, 'E')) {
                room[1] = ColourUtil.colourise("◄", ColourUtil.red);
            } else if (rooms.roomExists(x-1, y, z) && rooms.isLocked(x-1, y, z, 'E')) {
                room[1] = ColourUtil.colourise("|", ColourUtil.red);
            } else if (rooms.roomExists(x-1, y, z) && rooms.isClosed(x-1, y, z, 'E')) {
                room[1] = ColourUtil.colourise(">", ColourUtil.red);
            } else {
                room[1] = ColourUtil.colourise(">", ColourUtil.red);
            }
        } // If the west is closed
        else if (rooms.isClosed(x, y, z, 'W')) {
            if (rooms.roomExists(x-1, y, z) && rooms.isBlocked(x-1, y, z, 'E')) {
                room[1] = ColourUtil.colourise("◄", ColourUtil.yellow);
            } else if (rooms.roomExists(x-1, y, z) && rooms.isLocked(x-1, y, z, 'E')) {
                room[1] = ColourUtil.colourise("<", ColourUtil.red);
            } else if (rooms.roomExists(x-1, y, z) && rooms.isClosed(x-1, y, z, 'E')) {
                room[1] = ColourUtil.colourise("|", ColourUtil.yellow);
            } else {
                room[1] = ColourUtil.colourise(">", ColourUtil.yellow);
            }
        } // If the west is NOT obstructured
        else {
            if (rooms.roomExists(x-1, y, z) && rooms.isBlocked(x-1, y, z, 'E')) {
                room[1] = "◄";
            } else if (rooms.roomExists(x-1, y, z) && rooms.isLocked(x-1, y, z, 'E')) {
                room[1] = ColourUtil.colourise("<", ColourUtil.red);
            } else if (rooms.roomExists(x-1, y, z) && rooms.isClosed(x-1, y, z, 'E')) {
                room[1] = ColourUtil.colourise("<", ColourUtil.yellow);
            } else {
                room[1] = " ";
            }
        }
        
        // Contents
        boolean content = rooms.roomHasContent(x, y, z);
        String contentMarker;
        if(content) {
            contentMarker = ColourUtil.colourise(".", ColourUtil.darkYellow);
        } else {
            contentMarker = ColourUtil.colourise(".", ColourUtil.darkGrey);
        }
        
        String vertExitsMarker;
        if(rooms.roomExists(x, y, z+1) && !rooms.isBlocked(x, y, z, 'U')
                && !rooms.isBlocked(x, y, z, 'D') && rooms.roomExists(x, y, z-1)) {
            vertExitsMarker = "↨";
        } else if(rooms.roomExists(x, y, z+1) && !rooms.isBlocked(x, y, z, 'U')) {
            vertExitsMarker = "↑";
        } else if(rooms.roomExists(x, y, z-1) && !rooms.isBlocked(x, y, z, 'D')) {
            vertExitsMarker = "↓";
        } else {
            vertExitsMarker = contentMarker;
        }
        
        String specialInterestsMarker = " ";
        boolean vendors = rooms.getRoomVendors(x, y, z).length > 0;
        if(x == p.x() && y == p.y() && z == p.z()) {
            specialInterestsMarker = ColourUtil.colourise("Y", ColourUtil.player);
        } else if (vendors) {
            specialInterestsMarker = ColourUtil.colourise("$", ColourUtil.darkGreen);
        }
        
        room[1] += contentMarker + specialInterestsMarker + vertExitsMarker;



        return room;
    }
}
